package org.finmanager.core;

import org.finmanager.data.CategoryList;

import javax.swing.*;
import javax.swing.table.AbstractTableModel;

import java.util.ArrayList;

import static org.finmanager.core.Constants.MAX_FAVOURITE_CATEGORIES;
import static org.finmanager.core.Constants.CATEGORY_TABLE_COLUMN_NAME;

/**
 * Created by Kelvin on 2/4/2014.
 */

//defining models related to category table to be further used easily
public class CategoryTableModel extends AbstractTableModel {
	private CategoryList categoryList;

	public static final int NAME = 0;
	public static final int FAVOURITE = 1;
	public static final int FILTER = 2;

	public CategoryTableModel(CategoryModel categoryModel) {
		this.categoryList = categoryModel.getCategoryList();
	}

	@Override
	public int getRowCount() {
		return categoryList.getCategoryCount();
	}

	@Override
	public int getColumnCount() {
		return CATEGORY_TABLE_COLUMN_NAME.length;
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		Category category = categoryList.getCategory(rowIndex);
		switch (columnIndex) {
			case NAME       :return category.getName();
			case FAVOURITE  :return category.isFavourite();
			case FILTER     :return category.isFilterSelected();
			default         :return null;
		}
	}

	@Override
	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
		switch (columnIndex) {
			case FAVOURITE:
				categoryList.toggleFavourite(rowIndex);
				if (categoryList.getFavouriteCategoriesCount() > MAX_FAVOURITE_CATEGORIES) {
					categoryList.toggleFavourite(rowIndex);
					return;
				}
				fireTableCellUpdated(rowIndex, columnIndex);
				break;
			case FILTER:
				categoryList.toggleFilterSelection(rowIndex);
				break;
		}
	}

	@Override
	public String getColumnName(int column) {
		return CATEGORY_TABLE_COLUMN_NAME[column];
	}

	@Override
	public Class<?> getColumnClass(int columnIndex) {
		switch (columnIndex) {
			case NAME       :return Category.class;
			case FAVOURITE  :return Boolean.class;
			case FILTER     :return Boolean.class;
			default         :return null;
		}
	}

	@Override
	public boolean isCellEditable(int rowIndex, int columnIndex) {
		return columnIndex == FAVOURITE || columnIndex == FILTER;
	}

	public int addRow(Category category) {
		categoryList.addCategory(category);
		int rowIndex = categoryList.getCategoryCount() - 1;
		fireTableRowsInserted(rowIndex, rowIndex);
		return rowIndex;
	}

	public void deleteRow(int rowIndex) {
		if (rowIndex == -1) return;

		categoryList.deleteCategory(rowIndex);
		fireTableRowsDeleted(rowIndex, rowIndex);
	}

	public RowFilter<CategoryTableModel, Integer> getFilter() {
		ArrayList<RowFilter<Object, Object>> filters = new ArrayList<RowFilter<Object, Object>>();
		for (Category category : categoryList.getFilteredCategories()) {
			filters.add(RowFilter.regexFilter(category.toString(), ItemTableModel.CATEGORY));
		}
		return RowFilter.orFilter(filters);
	}

	public void resetFilter() {
		categoryList.resetFilterSelection();
	}
}
